/*
 * @Author: Du Weixing duweixing@sgsimulation.com
 * @Date: 2024-10-20 20:54:18
 * @LastEditors: Du Weixing duweixing@sgsimulation.com
 * @LastEditTime: 2024-12-05 09:34:04
 * @FilePath: \SGFEM\Solver\SectionCalculator\BeamSection\FormulaMethod\src\LBeamSectionFormulaCalculator.cpp
 * @Description: PBEAML L形（L）梁截面属性使用解析公式计算类
 * 
 * Copyright (c) 2024 by 神工仿真, All Rights Reserved. 
 */

#include "LBeamSectionFormulaCalculator.h"
#include <cmath>
#include <cstring>
#include "DataStructure/Common/Real.h"
#include "DataStructure/Common/Constant.h"

using SG::DataStructure::Common::Real;
using SG::DataStructure::Common::TOLERANCE;
using SG::DataStructure::FEM::PBEAMLData;
using SG::DataStructure::FEM::PBEAMData;
using SG::FEMSolver::Element::LBeamSectionFormulaCalculator;

PBEAMData LBeamSectionFormulaCalculator::Compute (const PBEAMLData& pBeamL) const
{
    PBEAMData pBeam;

    if (!std::strcmp (pBeamL.m_group, "MSCBML0"))
    {
        auto section = pBeamL.m_section;
        auto n       = section.size ();

        pBeam.m_id  = pBeamL.m_id;
        pBeam.m_mId = pBeamL.m_mId;

        // 恒截面 NSEGS CCF SECTION_LEN
        // 恒截面 1     1   2
        // 变截面 1     2   3
        // 变截面 2     0   4
        // 变截面 9     0   11
        // 变截面 10    0   11
        if (2 == n)
        {
            pBeam.m_nsges = 1;
        }
        else if (n > 2 && n < 11)
        {
            pBeam.m_nsges = n - 2;
        }
        else if (11 == n)
        {
            if (std::fabs (section[9].m_rdist - 1.0) < TOLERANCE)
            {
                pBeam.m_nsges = 9;
            }
            else
            {
                pBeam.m_nsges = 10;
            }
        }

        if (2 == n)
        {
            pBeam.m_ccf = 1;

        }
        else if (3 == n)
        {
            pBeam.m_ccf = 2;
        }

        auto nCompute = pBeam.m_nsges <= pBeam.m_ccf ? pBeam.m_ccf : pBeam.m_nsges + 1;
        for (size_t i = 0; i < nCompute; ++i)
        {
            pBeam.m_SO[i]  = section[i].m_so; // ToDo：变量名称大小
            pBeam.m_XXB[i] = section[i].m_rdist;

            const auto& dimension = section[i].m_dims;
            auto t1 = dimension[2];
            auto t2 = dimension[3];
            auto b  = dimension[0] - 0.5 * t2;
            auto h  = dimension[1] - 0.5 * t1;
            auto h2 = dimension[1] - t1;
            auto b1 = dimension[0] - t2;

            pBeam.m_A[i] = (b + 0.5 * t2) * t1 + h2 * t2;
            Real yC = t2 * h2 * (h2 + t1) / (2.0 * pBeam.m_A[i]);
            Real zC = t1 * b1 * (b1 + t2) / (2.0 * pBeam.m_A[i]);
            pBeam.m_I1[i]  = (b + 0.5 * t2) * t1 * t1 * t1 / 12.0 + (b + 0.5 * t2) * t1 * yC * yC + t2 * h2 * h2 * h2 / 12.0 +
                             t2 * h2 * (0.5 * (h2 + t1) - yC) * (0.5 * (h2 + t1) - yC);
            pBeam.m_I2[i]  = h2 * t2 * t2 * t2 / 12.0 + h2 * t2 * zC * zC + t1 * (b + 0.5 * t2) * (b + 0.5 * t2) * (b + 0.5 * t2) / 12.0 +
                             t1 * (b + 0.5 * t2) * (0.5 * b1 - zC) * (0.5 * b1 - zC);
            pBeam.m_I12[i] = t1 * t2 * zC * yC - b1 * t1 * yC * (0.5 * (b1 + t2) - zC) - h2 * t2 * zC * (0.5 * (h2 + t1) - yC);
            pBeam.m_J[i]   = (t1 * t1 * t1 * b + t2 * t2 * t2 * h) / 3.0;
            pBeam.m_NSM[i] = section[i].m_nsm; // ToDo：变量名称大小

            pBeam.m_C1[i] =  h;
            pBeam.m_C2[i] =  0.5 * t2;
            pBeam.m_D1[i] = -0.5 * t1;
            pBeam.m_D2[i] =  b;
            pBeam.m_E1[i] = -0.5 * t1;
            pBeam.m_E2[i] = -0.5 * t2;
            pBeam.m_F1[i] =  h;
            pBeam.m_F2[i] = -0.5 * t2;

            if (0 == i)
            {
                pBeam.m_K1  = h2 * t2 / pBeam.m_A[0];
                pBeam.m_K2  = b1 * t1 / pBeam.m_A[0];
                pBeam.m_N1A = yC;
                pBeam.m_N2A = zC;
            }
            if (nCompute - 1 == i)
            {
                pBeam.m_N1B = yC;
                pBeam.m_N2B = zC;
            }
        }
        if (nCompute != 11)
        {
            pBeam.m_SO[10]  = pBeam.m_SO[nCompute - 1];
            pBeam.m_XXB[10] = 1.0;
            pBeam.m_A[10]   = pBeam.m_A[nCompute - 1];
            pBeam.m_I1[10]  = pBeam.m_I1[nCompute - 1];
            pBeam.m_I2[10]  = pBeam.m_I2[nCompute - 1];
            pBeam.m_I12[10] = pBeam.m_I12[nCompute - 1];
            pBeam.m_J[10]   = pBeam.m_J[nCompute - 1];
            pBeam.m_NSM[10] = pBeam.m_NSM[nCompute - 1];
            pBeam.m_C1[10]  = pBeam.m_C1[nCompute - 1];
            pBeam.m_C2[10]  = pBeam.m_C2[nCompute - 1];
            pBeam.m_D1[10]  = pBeam.m_D1[nCompute - 1];
            pBeam.m_D2[10]  = pBeam.m_D2[nCompute - 1];
            pBeam.m_E1[10]  = pBeam.m_E1[nCompute - 1];
            pBeam.m_E2[10]  = pBeam.m_E2[nCompute - 1];
            pBeam.m_F1[10]  = pBeam.m_F1[nCompute - 1];
            pBeam.m_F2[10]  = pBeam.m_F2[nCompute - 1];
        }

        pBeam.m_CWA = 0.0; // ToDo
        pBeam.m_CWB = 0.0; // ToDo
    }

    return pBeam;
}